package me.buick.util.snmp.core;

import me.buick.util.snmp.core.dao.DiskInfoDAO;
import me.buick.util.snmp.core.dao.NetworkIfInfoDAO;
import me.buick.util.snmp.core.dao.ProcessInfoDAO;
import me.buick.util.snmp.core.dao.SystemInfoDAO;
import me.buick.util.snmp.core.dao.impl.snmp.SNMPPerfDAOFactory;


/**
 * Abstract performance DAOs factory. 
 * 
 * This factory applies the abstract factory design pattern, it can be used easily to get all performance monitor DAOs
 * like Disk info DAO, Network info DAO and so on.
 * 
 * @author buick
 */
public abstract class AbstractPerfDAOFactory {

	/**
	 * Get Abstract performance DAOs factory with the arguments 
	 * SupportedOS, SupportedProtocol, host (IP addr., or host name), port number and interval
	 * 
	 * Please note that the Performance monitor library has two working modes, 
	 * 
	 * 1: normal mode
	 * 
	 * Under this mode, the client and the library work like the client - server, the client request for something, the server will give client the 
	 * proper response.It is "stateless"
	 * 
	 * 2: enhancement mode
	 * 
	 * Under this mode, the library will start a unique background thread to feed the data to client as a specified interval. In this way, many clients
	 * of these library like JMeter, SNMP Monitor... can easily use this library for periodic performance monitor work.
	 * 
	 * Which mode will be used in the library depends on the interval arguments when you send to factory, if the interval <= 0, the library will work 
	 * under normal mode, if the interval > 0, the library will work under enhancement mode. 
	 * 
	 * @param os 
	 * @param protocol
	 * @param host
	 * @param port
	 * @param interval data fetch interval in seconds
	 * @return
	 */
	public static AbstractPerfDAOFactory getPerfDAOFactory(SupportedOS os, SupportedProtocol protocol, String host, int port, long interval){
		if(null == protocol || null == os || Utils.isEmptyString(host) || !Utils.isValidatePortNumber(port)){
			throw new IllegalArgumentException("One of your argument is unacceptable");
		}else{
			synchronized (AbstractPerfDAOFactory.class){
					if(interval <= 0){
						interval = 0;
					}
					return popPerfDAO(os, protocol, host, port, interval);
			}
		}
	}
	
	private static AbstractPerfDAOFactory popPerfDAO(SupportedOS os, SupportedProtocol protocol, String host, int port, long interval){
		AbstractPerfDAOFactory perfDAOFactory = null;
		switch (protocol) {
			case SNMP:
				perfDAOFactory = new SNMPPerfDAOFactory(os, host, port, interval);
				break;
		}
		return perfDAOFactory;
	}
	
	public abstract DiskInfoDAO getDiskInfoDAO();
	
	public abstract NetworkIfInfoDAO getNetworkIfInfoDAO();
	
	public abstract SystemInfoDAO getSystemInfoDAO();
	
	public abstract ProcessInfoDAO getProcessInfoDAO();
	
	public abstract boolean discardDAOs();

}
